import common from "shared/component/common/common";
import { container, ContainerService } from "shared/component/container/ContainerService";
import EventBinder from "shared/component/event/EventBinder";
import { hotConfig } from "shared/component/hotconfig/hotconfig";
import Log4R from "shared/component/log/Log4R";
import { resource } from "shared/component/resource/resource";
import TriggerBase from "shared/component/trigger/TriggerBase";
import WallHeader from "shared/component/trigger/WallHeader";

import { ColiGroup } from "shared/enums/ColiGroup";

const loginfo = Log4R.getLog('info');
const lightingConfig = {
    Ambient: Color3.fromRGB(200, 200, 200),
    Brightness: 0,
    ClockTime: 0,
    GeographicLatitude: 0,
    GlobalShadows: false,

}
export class ScenceServiceImpl extends ContainerService<Ctn.ScenceService, Ctn.ScenceEntity> implements Ctn.ScenceService {
    /** 当前场景实体 */
    protected currentScenceEntity?: Ctn.ScenceEntity
    getCurrentScenceEntity(): Ctn.ScenceEntity | undefined {
        throw ("Method not implemented.");
    }
    protected serverCalls: (keyof this)[] = [];
    protected serviceName: keyof Ctn.Services = "scenceService";
    /** 加载场景绑定器 */
    protected loadScenceBinder = new EventBinder<(
        /** 进入区域参数 */
        scenceEntity: Ctn.ScenceEntity
    ) => void>();
    /** */
    onLoadScence = this.loadScenceBinder.bind();

    /** 触发器绑定 */
    protected triggerBinder = new EventBinder<(
        /** 触发器 */
        trigger: clazz.TriggerBase,
        /** 触碰物 */
        part: BasePart
    ) => void>();
    /** */
    onTrigger = this.triggerBinder.bind();
    /** 区域进入事件绑定器 */
    private areaEnterBinder = new EventBinder<(
        /** 进入区域参数 */
        param: Ctn.scence.EnterAreaEntity
    ) => void>()
    /** 区域进入事件回调 */
    onAreaEnter = this.areaEnterBinder.bind();
    /** 灯光库 */
    private lightings = new Map<string, {
        config: Lighting,
        children: Instance[]
    }>();
    /** 灯光库 */
    private currentLighting = "default"



    public hot() {
        this.scan(script.Parent?.Parent?.FindFirstChild('hot'))
    }
    public init(): void {
        hotConfig(resource.getPath("lua.Lighting", game.GetService('ReplicatedStorage')), c => {
            // print("new", c)
            if (c.IsA('ModuleScript')) {
                const lightingConfig = require(c) as Lighting;
                this.lightings.set(c.Name, {
                    config: lightingConfig,
                    children: c.GetChildren()
                })
                if (this.currentLighting === c.Name) {
                    this.setLighting(lightingConfig, c.GetChildren())
                }
            }
        })
        task.spawn(() => {
            while (!this.lightings.has(this.currentLighting)) {
                print('not find light', this.currentLighting)
                task.wait(1)
            }
            const currentConfig = this.lightings.get(this.currentLighting);
            if (currentConfig)
                this.setLighting(currentConfig.config, currentConfig.children)
        })
    }
    private setLighting(lightingConfig: Lighting, childs: Instance[]) {
        const Lighting = game.GetService('Lighting');
        Lighting.Ambient = lightingConfig.Ambient;
        Lighting.Brightness = lightingConfig.Brightness;
        Lighting.ClockTime = lightingConfig.ClockTime;
        Lighting.GeographicLatitude = lightingConfig.GeographicLatitude;
        Lighting.GlobalShadows = lightingConfig.GlobalShadows;
        Lighting.ClearAllChildren();
        childs.forEach(c => {
            c.Clone().Parent = Lighting;
        })
    }
    /** 当前区域 */
    private currentArea: string | undefined
    /**
     * 设置区域入口检测 
     * @param enterPart 检测触发器
     */
    private setAreaEnter(enterPart: Part) {
        enterPart.CollisionGroup = ColiGroup.trigger;//设置触发器碰撞组
        enterPart.CanCollide = false;//设置触发器碰撞属性
        enterPart.Transparency = 1;//设置碰撞器透明度
        enterPart.Touched.Connect(c => {
            // loginfo?.info('touched', enterPart)
            /** 碰撞器所在区域 */
            const area = common.getAncestorByLevel(enterPart, 2);
            if (this.currentArea === area.Name) {

            } else {
                this.currentArea = area.Name
                // loginfo?.info('area', area)
                /** 区域设置 */
                const areaConfig = this.currentScenceEntity?.config?.areas[area.Name]
                if (area) {
                    this.areaEnterBinder.callBack({
                        areaName: area.Name,
                        enterPart,
                        areaConfig: areaConfig
                    })
                }
            }

        })
    }
    /** 过滤物品 */
    public filterObj(obj: Configuration) {

        switch (obj.Name as keyof clazz.Instances) {
            case "areaEnter":
                if (obj.Parent?.IsA('Part')) {
                    this.setAreaEnter(obj.Parent)
                }
                return true
            case "WallHeader":
                const wallHeader = new WallHeader(obj)
                this.setTrigger(wallHeader)
                return true
        }

        return false
    }
    /** 给机关设置触发事件 */
    private setTrigger(trigger: TriggerBase) {
        trigger.onTouch(c => {
            this.triggerBinder.callBack(trigger, c)
        })
    }

    /**
     * 同步当前场景配置
     */
    public syncCurrentScenceEntity(entity: Ctn.ScenceEntity) {
        loginfo?.info('syncCurrentScenceEntity', entity)
        this.currentScenceEntity = entity
        this.loadScenceBinder.callBack(entity)
    }
}